package org.jeecg.modules.lottery.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.bid.service.IBidService;
import org.jeecg.modules.lottery.entity.Lottery;
import org.jeecg.modules.lottery.entity.LotteryManagement;
import org.jeecg.modules.lottery.mapper.LotteryMapper;
import org.jeecg.modules.lottery.service.ILotteryManagementService;
import org.jeecg.modules.lottery.service.ILotteryRulesService;
import org.jeecg.modules.lottery.service.ILotteryService;
import org.jeecg.modules.message.service.IProcurementMessageService;
import org.jeecg.modules.purchase.entity.PurchasePlan;
import org.jeecg.modules.supplier.entity.Supplier;
import org.jeecg.modules.supplier.service.ISupplierService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.web.client.RestTemplate;
import org.springframework.beans.factory.annotation.Autowired;

@Service
@Slf4j
public class LotteryServiceImpl extends ServiceImpl<LotteryMapper, Lottery> implements ILotteryService {

    @Autowired
    private LotteryMapper lotteryMapper;

    @Autowired
    private ISupplierService supplierService;

    @Autowired
    private ILotteryManagementService lotteryManagementService;

    @Autowired
    private ILotteryService lotteryService;

    @Autowired
    public IBidService bidService;

    @Autowired
    private ILotteryRulesService lotteryRulesService;

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private IProcurementMessageService procurementMessageService;

    @Transactional
    public List<Lottery> conductLottery(String id,String purchaseId, String category, int drawCount, String operator) {
        List<Supplier> eligibleSuppliers = supplierService.getSuppliersForLottery(category);
            // 获取符合条件的供应商 列表
        if (eligibleSuppliers.size() < drawCount) {
            throw new RuntimeException("符合条件的供应商数量不足，无法进行抽签");
        }
        List<Supplier> selectedSuppliers = lotteryRulesService.drawLottery(eligibleSuppliers, drawCount);

        //记录抽奖历史
        List<Lottery> lotteries = new ArrayList<>();
        StringBuilder winningSuppliers = new StringBuilder();
        for (int i = 0; i < selectedSuppliers.size(); i++) {
            Supplier supplier = selectedSuppliers.get(i);
            //中签的供应商发消息通知
            procurementMessageService.sendLotteryWinningMessage(supplier.getId(),id);
            Lottery lottery = new Lottery();
            lottery.setPurchaseId(purchaseId);
            lottery.setSupplierId(supplier.getId());
            lottery.setLotteryStatus("1");
            lottery.setCompanyName(supplier.getCompanyName());
            lottery.setLotteryTime(new Date());
            lottery.setLotteryOperator(operator);
            lottery.setLotteryRound(1);
            lottery.setCreateBy(operator);
            lottery.setCreateTime(new Date());
            // 正确拼接供应商名称，避免末尾多余的逗号
            winningSuppliers.append(supplier.getCompanyName());
            if (i < selectedSuppliers.size() - 1) {
                winningSuppliers.append(",");
            }

            lotteries.add(lottery);
        }
        this.saveBatch(lotteries);
        // 遍历保存后的lottery对象，为每个抽中供应商添加投标
        for (Lottery savedLottery : lotteries) {
            if (savedLottery.getId() != null) {
                bidService.addbiditem(purchaseId, savedLottery.getId(), operator);
            } else {
                log.error("抽签成功但获取LotteryID失败，跳过添加投标，供应商：{}", savedLottery.getCompanyName());
            }
        }
       LotteryManagement lotteryManagement = lotteryManagementService.getById(id);
            lotteryManagement.setWinningSuppliers(winningSuppliers.toString());
            lotteryManagement.setStatus("1");//抽签状态：0-未抽签，1-已抽
            lotteryManagement.setParticipantCount(eligibleSuppliers.size());
            lotteryManagement.setCompleteTime(new Date());
            lotteryManagement.setDrawPerson(operator);
            lotteryManagement.setDrawQuantity(drawCount);
            lotteryManagementService.updateById(lotteryManagement);



        log.info("抽签完成,方案ID：{}，抽中供应商数量：{}", purchaseId, lotteries.size());
        return lotteries;
    }


    @Transactional
    public List<Lottery> conductSupplementaryLottery(String id,String purchaseId ,String category, int supplementCount, String operator) {
        List<String> selectedSupplierIds = lotteryMapper.getSelectedSupplierIds(purchaseId);

        List<Supplier> eligibleSuppliers = supplierService.getSuppliersForLottery(category);

        //筛选出尚未被选中的供应商
        List<Supplier> remainingSuppliers = eligibleSuppliers.stream()
                .filter(supplier -> !selectedSupplierIds.contains(supplier.getId()))
                .collect(Collectors.toList());
// 师弟认真看：eligibleSuppliers.stream()：将 eligibleSuppliers 列表转换为流（Stream）。
//.filter(supplier -> !selectedSupplierIds.contains(supplier.getId()))：使用 filter 方法过滤掉已经选中的供应商。
// supplier.getId() 获取当前供应商的 ID，selectedSupplierIds.contains(supplier.getId()) 检查该 ID 是否已经存在于已选中的供应商 ID 列表中。如果不存在，则保留该供应商。
//.collect(Collectors.toList())：将过滤后的流重新收集为一个列表。
//        remainingSuppliers：存储尚未被选中的供应商列表。

        if (remainingSuppliers.size() < supplementCount) {
            throw new RuntimeException("剩余符合条件的供应商数量不足，无法进行补抽");
        }
        List<Supplier> selectedSuppliers = lotteryRulesService.drawLottery(remainingSuppliers, supplementCount);

        StringBuilder winningSuppliers = new StringBuilder();
        List<Lottery> lotteries = new ArrayList<>();
        for (int i = 0; i < selectedSuppliers.size(); i++) {
            Supplier supplier = selectedSuppliers.get(i);
            //中签通知
            procurementMessageService.sendLotteryWinningMessage(supplier.getId(),id);
            Lottery lottery = new Lottery();
            lottery.setPurchaseId(purchaseId);
            lottery.setSupplierId(supplier.getId());
            lottery.setCompanyName(supplier.getCompanyName());
            lottery.setLotteryStatus("1");
            lottery.setLotteryTime(new Date());
            lottery.setLotteryOperator(operator);
            lottery.setLotteryRound(2);
            lottery.setCreateBy(operator);
            lottery.setCreateTime(new Date());
            lotteries.add(lottery);
            // 正确拼接供应商名称，避免末尾多余的逗号
            winningSuppliers.append(supplier.getCompanyName());
            if (i < selectedSuppliers.size() - 1) {
                winningSuppliers.append(",");
            }
        }
        this.saveBatch(lotteries);
        // 遍历保存后的lottery对象，为每个抽中供应商添加投标
        for (Lottery savedLottery : lotteries) {
            if (savedLottery.getId() != null) {
                bidService.addbiditem(purchaseId, savedLottery.getId(), operator);
            } else {
                log.error("抽签成功但获取LotteryID失败，跳过添加投标，供应商：{}", savedLottery.getCompanyName());
            }
        }
        LotteryManagement lotteryManagement = lotteryManagementService.getById(id);
        // 原有的加上新的，使用append方法正确拼接
        winningSuppliers.append(",").append(lotteryManagement.getWinningSuppliers());

        lotteryManagement.setWinningSuppliers(winningSuppliers.toString());
        lotteryManagement.setStatus("1");//抽签状态：0-未抽签，1-已抽
        lotteryManagement.setCompleteTime(new Date());
        lotteryManagement.setDrawPerson(operator);
        lotteryManagementService.updateById(lotteryManagement);



        // 遍历保存后的lottery对象，为每个抽中供应商添加投标
        for (Lottery savedLottery : lotteries) {
            if (savedLottery.getId() != null) {
                bidService.addbiditem(purchaseId, savedLottery.getId(), operator);
            } else {
                log.error("抽签成功但获取LotteryID失败，跳过添加投标，供应商：{}", savedLottery.getCompanyName());
            }
        }
        log.info("补抽完成，方案ID：{}，补抽供应商数量：{}", purchaseId, lotteries.size());
        return lotteries;
    }

//    private List<Supplier> weightedRandomSelect(List<Supplier> suppliers, int count) {
//        List<Supplier> result = new ArrayList<>();
//        List<WeightedSupplier> weightedSuppliers = new ArrayList<>();
//
//        for (Supplier supplier : suppliers) {
//            BigDecimal winningRate = supplier.getWinningRate();
//            if (winningRate == null) {
//                winningRate = BigDecimal.ZERO;
//            }
//
//            double weight = 1.0 - winningRate.doubleValue();
//            if (weight <= 0) {
//                weight = 0.1;
//            }
//
//            BigDecimal totalScore = supplier.getTotalScore();
//            if (totalScore != null && totalScore.compareTo(new BigDecimal("60")) < 0) {
//                weight *= 0.5;
//            }
//
//            weightedSuppliers.add(new WeightedSupplier(supplier, weight));
//        }
//
//        double totalWeight = weightedSuppliers.stream().mapToDouble(ws -> ws.weight).sum();
//        Random random = new Random();
//
//        for (int i = 0; i < count; i++) {
//            double randomValue = random.nextDouble() * totalWeight;
//            double currentWeight = 0;
//
//            for (int j = 0; j < weightedSuppliers.size(); j++) {
//                WeightedSupplier ws = weightedSuppliers.get(j);
//                currentWeight += ws.weight;
//                if (randomValue <= currentWeight) {
//                    result.add(ws.supplier);
//                    weightedSuppliers.remove(j);
//                    totalWeight -= ws.weight;
//                    break;
//                }
//            }
//        }
//
//        return result;
//    }

    @Override
    @Transactional
    public boolean abandonLottery(String Id, String operator,String remark) {
        Lottery lottery = this.getById(Id);
        if (lottery == null) {
            return false;
        }
        lottery.setRemark(remark);//填写放弃原因
        lottery.setLotteryStatus("2");
        String companyName = lottery.getCompanyName();
        //查询proc_lottery_management的字段winningSuppliers，并要去掉公司名字companyName.
        lotteryService.removeWinningSupplier(Id, companyName);
        return this.updateById(lottery);
    }

    @Override
    public List<PurchasePlan> getEligiblePurchasePlan(String category) {
        return lotteryMapper.getEligiblePurchasePlan(category);
    }

    @Override
    public List<Lottery> getLotteryResults(String lotteryStatus) {
        QueryWrapper<Lottery> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("lottery_status", lotteryStatus);
        queryWrapper.orderByAsc("lottery_round", "create_time");
        return this.list(queryWrapper);
    }

    @Override
    public boolean hasLotteryForpurchase(String purchaseId) {
        QueryWrapper<Lottery> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("purchase_id", purchaseId);
        return this.count(queryWrapper) > 0;
    }

    @Override
    public List<Lottery> getLotteryResultsByStatusAndPurchaseId(String lotteryStatus, String purchaseId) {
        QueryWrapper<Lottery> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("purchase_id", purchaseId);
        if (lotteryStatus != null && !lotteryStatus.isEmpty()) {
            queryWrapper.eq("lottery_status", lotteryStatus);
        }
        queryWrapper.orderByAsc("lottery_round", "create_time");
        return this.list(queryWrapper);
    }

    @Override
    public String getWinningSupplierNamesByPurchaseId(String purchaseId) {
        // 查询状态为1（中签）的抽签记录
        List<Lottery> winningLotteries = getLotteryResultsByStatusAndPurchaseId("1", purchaseId);

        // 如果没有记录，返回空字符串
        if (winningLotteries.isEmpty()) {
            return "";
        }

        // 获取第一个记录的category以查询供应商信息
        String category = null;
        if (!winningLotteries.isEmpty()) {
            // 从lotteryManagement中获取category
            List<LotteryManagement> lotteryManagements = lotteryManagementService.list(
                new QueryWrapper<LotteryManagement>().eq("purchase_id", purchaseId)
            );
            if (!lotteryManagements.isEmpty()) {
                category = lotteryManagements.get(0).getCategory();
            }
        }

        // 获取符合条件的供应商列表
        List<Supplier> eligibleSuppliers = supplierService.getSuppliersForLottery(category);


        // 合并中签供应商名称
        StringBuilder winningSupplierNames = new StringBuilder();
        for (Lottery winningLottery : winningLotteries) {
            for (Supplier supplier : eligibleSuppliers) {
                if (supplier.getId().equals(winningLottery.getSupplierId())) {
                    if (winningSupplierNames.length() > 0) {
                        winningSupplierNames.append(",");
                    }
                    winningSupplierNames.append(supplier.getCompanyName());
                    break;
                }
            }
        }

        return winningSupplierNames.toString();
    }
    private static class WeightedSupplier {
        Supplier supplier;
        double weight;

        WeightedSupplier(Supplier supplier, double weight) {
            this.supplier = supplier;
            this.weight = weight;
        }
    }

    @Override
    @Transactional
    public boolean removeWinningSupplier(String lotteryId, String companyName) {
        // 1. 根据lotteryId查询抽奖记录
        Lottery lottery = this.getById(lotteryId);
        if (lottery == null) {
            log.error("未找到指定的抽奖记录，lotteryId: {}", lotteryId);
            return false;
        }
        // 1. 根据PurchaseId查询抽奖记录
        String purchaseId = lottery.getPurchaseId();
        if (purchaseId == null) {
            log.error("抽奖记录缺少采购方案ID，lotteryId: {}", lotteryId);
            return false;
        }


        // 使用 purchaseId 查询 proc_lottery_management 表中的记录。
        List<LotteryManagement> lotteryManagements = lotteryManagementService.list(
            new QueryWrapper<LotteryManagement>().eq("purchase_id", purchaseId)
        );

        if (lotteryManagements.isEmpty()) {
            log.error("未找到对应的抽签管理记录，purchaseId: {}", purchaseId);
            return false;
        }
//        获取第一个匹配的记录。（可以除去）
        LotteryManagement lotteryManagement = lotteryManagements.get(0);
        String winningSuppliers = lotteryManagement.getWinningSuppliers();

        // 3. 如果winningSuppliers为空，直接返回失败
        if (winningSuppliers == null || winningSuppliers.isEmpty()) {
            log.error("winningSuppliers字段为空，无法移除供应商");
            return false;
        }

        // 4. 从winningSuppliers中移除指定的companyName
        StringBuilder updatedWinningSuppliers = new StringBuilder();//StringBuilder 是一个可变的字符序列，用于高效地构建和操作字符串。
        String[] suppliers = winningSuppliers.split(",");//分割WinningSuppliers，将 winningSuppliers 按逗号分隔成数组。
        boolean found = false;
//      遍历数组，将不等于 companyName 的供应商名称重新拼接成字符串。
        for (int i = 0; i < suppliers.length; i++) {
            String supplierName = suppliers[i].trim();
            if (!supplierName.equals(companyName)) {
                if (updatedWinningSuppliers.length() > 0) {
                    updatedWinningSuppliers.append(",");
                }
                updatedWinningSuppliers.append(supplierName);
            } else {
                found = true;//如果找到了要移除的供应商名称，将 found 设置为 true。
            }
        }

        // 5. 如果没有找到要移除的公司名称，返回失败
        if (!found) {
            log.error("未在winningSuppliers中找到指定的公司名称: {}", companyName);
            return false;
        }

        // 6. 更新winningSuppliers字段
        lotteryManagement.setWinningSuppliers(updatedWinningSuppliers.toString());//将 StringBuilder 对象 updatedWinningSuppliers 转换为字符串
        boolean updateResult = lotteryManagementService.updateById(lotteryManagement);

        if (updateResult) {
            log.info("成功从winningSuppliers中移除公司名称: {}, purchaseId: {}", companyName, purchaseId);
        } else {
            log.error("更新winningSuppliers字段失败");
        }

        return updateResult;
    }


}
